package cn.learn.async.threadpool;

import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/*
 * 阿里Java规约禁止使用Java内置 Executors 创建线程池
 * ThreadPoolTaskExecutor
 * ScheduleThreadPoolExecutor
 * ForkJoinPool
 *
 * 这三类,这里说ThreadPoolTaskExecutor
 * */
/**
 * 创建线程池
 * 注解开启异步任务支持 @EnableAsync
 * 扫描指使用的异步线程的包位置 @ComponentScan({"com.ihyht.app.module.dsjglpt.sjzlgl.rds.odps.service","com.ihyht.app.module.dsjglpt.sjzlgl.rds.rwdd.threadcomponent"})
 *
 * @author huangyezhan
 * @version 1.0
 * @date 2020年03月01日20:48
 */
@Configuration
@EnableAsync
public class ThreadPoolExecutorDemo implements AsyncConfigurer {


    /**
     * 配置类实现AsyncConfigurer接口并重写getAsyncExcutor方法，并返回一个ThreadPoolTaskExevutor 获得了一个基于线程池的TaskExecutor
     * <p>
     * corePoolSize => 线程池核心线程数量
     * maximumPoolSize => 线程池最大数量
     * keepAliveTime => 空闲线程存活时间
     * unit => 时间单位
     * workQueue => 线程池所使用的缓冲队列
     * threadFactory => 线程池创建线程使用的工厂
     * handler => 线程池对拒绝任务的处理策略
     */
    @Override
    public Executor getAsyncExecutor() {
        int cpuNum = Runtime.getRuntime().availableProcessors();
        System.out.println("========================================CUP数量：" + cpuNum);

        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        //线程池维护线程的最少数量
        taskExecutor.setCorePoolSize(cpuNum);
        taskExecutor.setMaxPoolSize(cpuNum * 2);
        //线程池所使用的缓冲队列
        taskExecutor.setQueueCapacity(500);
        //线程池维护线程所允许的空闲时间
        taskExecutor.setKeepAliveSeconds(30 * 60);
        //taskExecutor.setRejectedExecutionHandler();
        
        taskExecutor.setThreadNamePrefix("线程名称前缀：");
        taskExecutor.initialize();
        return taskExecutor;
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }


}
